/* * Copyright 2011 PrimeFaces Extensions. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * $Id: RemoteCommandRenderer.java 491 2011-11-29 13:41:23Z Zoigln@googlemail.com $ */ package org.primefaces.extensions.component.remotecommand; import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.Map; import javax.el.ELContext; import javax.el.ValueExpression; import javax.faces.FacesException; import javax.faces.component.UIComponent; import javax.faces.context.FacesContext; import javax.faces.context.ResponseWriter; import javax.faces.convert.Converter; import javax.faces.event.ActionEvent; import javax.faces.event.PhaseId; import org.primefaces.component.api.AjaxSource; import org.primefaces.renderkit.CoreRenderer; import org.primefaces.util.ComponentUtils; /** * Renderer for the {@link RemoteCommand} component. * * @author Thomas Andraschko / last modified by $Author: Zoigln@googlemail.com $ * @version $Revision: 491 $ * @since 0.2 */ public class RemoteCommandRenderer extends CoreRenderer { @Override public void decode(final FacesContext context, final UIComponent component) { final RemoteCommand command = (RemoteCommand) component; final Map<String, String> params = context.getExternalContext().getRequestParameterMap(); final String clientId = command.getClientId(context); if (params.containsKey(clientId)) { final ActionEvent event = new ActionEvent(command); if (command.isImmediate()) { event.setPhaseId(PhaseId.APPLY_REQUEST_VALUES); } else { event.setPhaseId(PhaseId.INVOKE_APPLICATION); } //apply params final ELContext elContext = context.getELContext(); for (final RemoteCommandParameter param : getParameters(command)) { if (!param.isRendered()) { continue; } final ValueExpression valueExpression = param.getApplyTo(); final String paramValue = params.get(clientId + "_" + param.getName()); final Converter converter = param.getConverter(); if (converter != null) { final Object convertedValue = converter.getAsObject(context, param, paramValue); valueExpression.setValue(elContext, convertedValue); } else { valueExpression.setValue(elContext, paramValue); } } command.queueEvent(event); } } @Override public void encodeEnd(final FacesContext context, final UIComponent component) throws IOException { final ResponseWriter writer = context.getResponseWriter(); final RemoteCommand command = (RemoteCommand) component; final List<RemoteCommandParameter> parameters = getParameters(command); //script writer.startElement("script", command); writer.writeAttribute("type", "text/javascript", null); writer.writeAttribute("id", command.getClientId(), null); writer.write(command.getName() + " = function("); //parameters for (int i = 0; i < parameters.size(); i++) { if (i != 0) { writer.write(","); } final RemoteCommandParameter param = parameters.get(i); writer.write(param.getName()); } writer.write(") {"); writer.write(buildAjaxRequest(context, command, parameters)); writer.write("}"); writer.endElement("script"); } protected String buildAjaxRequest(final FacesContext context, final AjaxSource source, final List<RemoteCommandParameter> parameters) { final UIComponent component = (UIComponent) source; final String clientId = component.getClientId(context); final UIComponent form = ComponentUtils.findParentForm(context, component); if (form == null) { throw new FacesException("Component " + component.getClientId(context) + " must be enclosed in a form."); } final StringBuilder req = new StringBuilder(); req.append("PrimeFaces.ab("); //form req.append("{formId:").append("'").append(form.getClientId(context)).append("'"); //source req.append(",source:").append("'").append(clientId).append("'"); //process String process = source.getProcess(); if (process == null) { process = "@all"; } else { process = ComponentUtils.findClientIds(context, component, process); //add @this if (process.indexOf(clientId) == -1) { process = process + " " + clientId; } } req.append(",process:'").append(process).append("'"); //update if (source.getUpdate() != null) { req.append(",update:'"); req.append(ComponentUtils.findClientIds(context, component, source.getUpdate())); req.append("'"); } //async if (source.isAsync()) { req.append(",async:true"); } //global if (!source.isGlobal()) { req.append(",global:false"); } //callbacks if (source.getOnstart() != null) { req.append(",onstart:function(){").append(source.getOnstart()).append(";}"); } if (source.getOnerror() != null) { req.append(",onerror:function(xhr, status, error){").append(source.getOnerror()).append(";}"); } if (source.getOnsuccess() != null) { req.append(",onsuccess:function(data, status, xhr){").append(source.getOnsuccess()).append(";}"); } if (source.getOncomplete() != null) { req.append(",oncomplete:function(xhr, status, args){").append(source.getOncomplete()).append(";}"); } //params req.append(",params:{"); for (int i = 0; i < parameters.size(); i++) { if (i != 0) { req.append(","); } final RemoteCommandParameter param = parameters.get(i); req.append("\""); req.append(clientId).append("_").append(param.getName()); req.append("\""); req.append(":").append(param.getName()); } req.append("}});"); return req.toString(); } protected final List<RemoteCommandParameter> getParameters(final RemoteCommand command) { final List<RemoteCommandParameter> parameters = new ArrayList<RemoteCommandParameter>(); for (final UIComponent child : command.getChildren()) { if (child instanceof RemoteCommandParameter) { parameters.add((RemoteCommandParameter) child); } } return parameters; } }